﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using AzukiMap.Tools.Logger;
using AzukiMap.Map;
using AzukiMap.Layer;
using AzukiMap.MapSource;
using System.Windows.Browser;
using System.Windows.Threading;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
using AzukiMap.Layer.Tile;
using AzukiMap.MapSource.Vector;
using AzukiMap.Renderer;
using AzukiMap.Request;
using Geotools.Geometries;
using Geotools.IO;

namespace AzukiMapUI
{
    public partial class Page : UserControl
    {
        const int LAYER_CONTROL_COLUMN = 0;
        const int LAYER_CONTROL_ROW = 2;
        const int LOGGER_CONTROL_COLUMN = 0;
        const int LOGGER_CONTROL_ROW = 4;
        const string LAYOUT_ROOT_XNAME = "LayoutRoot";
        const string MAP_CANVAS_XNAME = "MapCanvas";

        Grid _layoutRoot;
        LayerControl _layerControl;
        LogDisplay _logDisplay;
        MapControl _mapControl;
        DispatcherTimer _memUsageTimer;


        public Page()
        {
            // Required to initialize variables
            InitializeComponent();

            // Set a resize handler
            App.Current.Host.Content.Resized += new EventHandler(OnContentResized);

            _layoutRoot = (Grid)FindName(LAYOUT_ROOT_XNAME);

            _layerControl = WndLayerControl;
            _logDisplay = WndLogDisplay;

            _mapControl = new MapControl(MapCanvas);
            _mapControl.Srid = 4326;

            SetMapCanvasEvents();

            _mapControl.MoveToExtents(139.520, 34.0799, 139.532, 34.0921);

            SetLayerSelectedEvent();
            SetMemoryUsageView();

            SetMiyakeSamples();
            SetVE();
            SetGSI();
            SetWMSLayer();

            Logger.LogLevel = LogLevel.Debug;
        }

        void SetBackground(Brush brush)
        {
            MapCanvas.Background = brush;
        }

        void _mapControl_LayerAdded(object sender, LayerAddedArgs e)
        {
            _layerControl.Layers = e.Layers;
        }

        void SetMemoryUsageView()
        {
            _memUsageTimer = new DispatcherTimer();
            _memUsageTimer.Interval = TimeSpan.FromSeconds(10);
            _memUsageTimer.Tick += new EventHandler(_memUsageTimer_Tick);
            _memUsageTimer.Start();
        }

        void SetMapCanvasEvents()
        {
            _mapControl.MapExtentChanged += new MapExtentChangedHandler(control_MapExtentChanged);
            _mapControl.MapScaleChanged+=new MapScaleChangedHandler(control_MapScaleChanged);
            _mapControl.LayerAdded += new LayerAddedHandler(_mapControl_LayerAdded);
        }

        void SetLayerSelectedEvent()
        {
            WndLayerSelecter.MapSourceSelected += new MapSourceSelectedHandler(WndLayerSelecter_MapSourceSelected);
        }

        void WndLayerSelecter_MapSourceSelected(object sender, MapSourceSelectedArgs e)
        {
            MapSource newSource = e.MapSource;
            MapCanvas newCanvas = _mapControl.CreateMapCanvas();

            ILayer newLayer = CreateLayer(newSource, newCanvas);
            _mapControl.AddLayer(newLayer);
        }

        void control_MapScaleChanged(object sender, MapScaleChangedArgs e)
        {
            mapScale.Text = "1:" + e.Scale.ToString();
        }

        void control_MapExtentChanged(object sender, MapExtentChangedArgs e)
        {
            double[] extents = e.Extent;
            mapRectX1.Text = extents[(int)ExtentMinMax.MIN_X].ToString();
            mapRectY1.Text = extents[(int)ExtentMinMax.MIN_Y].ToString();
            mapRectX2.Text = extents[(int)ExtentMinMax.MAX_X].ToString();
            mapRectY2.Text = extents[(int)ExtentMinMax.MAX_Y].ToString();
        }

        void OnContentResized(object sender, EventArgs e)
        {
            Width = App.Current.Host.Content.ActualWidth;
            Height = App.Current.Host.Content.ActualHeight;
        }

        void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            WndLayerSelecter.Visibility = Visibility.Visible;

        }

        void WndLayerControl_AddLayerPressed(object sender)
        {
            WndLayerSelecter.Visibility = Visibility.Visible;
        }

        void WndLayerExpression_LayerSettingPressed(object sender, ILayer layer)
        {
        }

        ILayer CreateLayer(MapSource mapSource, MapCanvas mapCanvas)
        {
            if (mapSource.GetType() == typeof(PostGisSource))
            {
                return CreateLayer((PostGisSource)mapSource, mapCanvas);
            }
            if (mapSource.GetType() == typeof(WMSSource))
            {
                return CreateLayer((WMSSource)mapSource, mapCanvas);
            }
            if (mapSource.GetType() == typeof(RasterFileSource))
            {
                return CreateLayer((RasterFileSource)mapSource, mapCanvas);
            }
            if (mapSource.GetType() == typeof(KaMapSource))
            {
                return CreateLayer((KaMapSource)mapSource, mapCanvas);
            }
            if (mapSource.GetType() == typeof(VirtualEarthSource))
            {
                return CreateLayer((VirtualEarthSource)mapSource, mapCanvas);
            }
            if (mapSource.GetType() == typeof(GoogleMapSource))
            {
                return CreateLayer((GoogleMapSource)mapSource, mapCanvas);
            }
            return null;
        }

        ILayer CreateLayer(PostGisSource mapSource, MapCanvas mapCanvas)
        {
            PostGisLayer newLayer = new PostGisLayer(mapSource, mapCanvas, mapSource.Name);
            return newLayer;
        }

        ILayer CreateLayer(WMSSource mapSource, MapCanvas mapCanvas)
        {
            WMSLayer newLayer = new WMSLayer(mapSource, mapCanvas, mapSource.Name);
            return newLayer;
        }

        ILayer CreateLayer(RasterFileSource mapSource, MapCanvas mapCanvas)
        {
            RasterLayer newLayer = new RasterLayer(mapSource, mapCanvas, mapSource.Name);
            return newLayer;
        }

        ILayer CreateLayer(KaMapSource mapSource, MapCanvas mapCanvas)
        {
            KaMapLayer newLayer = new KaMapLayer(mapSource, mapCanvas, mapSource.Name);
            return newLayer;
        }

        ILayer CreateLayer(GoogleMapSource mapSource, MapCanvas mapCanvas)
        {
            GoogleMapLayer newLayer = new GoogleMapLayer(mapSource, mapCanvas, mapSource.Name);
            return newLayer;
        }

        ILayer CreateLayer(VirtualEarthSource mapSource, MapCanvas mapCanvas)
        {
            VirtualEarthLayer newLayer = new VirtualEarthLayer(mapSource, mapCanvas, mapSource.Name);
            return newLayer;
        }

        void _memUsageTimer_Tick(object sender, EventArgs e)
        {
            memoryUsage.Text = (GC.GetTotalMemory(false) / 1024 / 1024).ToString();
        }

        void Sweep()
        {
            GC.Collect();
        }

        public void SetVE()
        {
            VirtualEarthSource veSource = new VirtualEarthSource("Virtual Earth");
            //veSource.TileType = VirtualEarthLayerType.HYBRID;
            veSource.TileType = VirtualEarthLayerType.ROAD;
            MapCanvas veCanvas = _mapControl.CreateMapCanvas();
            VirtualEarthLayer veLayer = new VirtualEarthLayer(veSource, veCanvas, "Virtual Earth");
            veCanvas.Opacity = 1;
            veLayer.Visiblity = Visibility.Visible;
            _mapControl.AddLayerButtom(veLayer);
        }

        public void SetGSI()
        {
            GsiSource gsiSource = new GsiSource();
            MapCanvas gsiCanvas = _mapControl.CreateMapCanvas();
            GsiLayer gsiLayer = new GsiLayer(gsiSource, gsiCanvas, "GSI");
            gsiLayer.Visiblity = Visibility.Collapsed;
            gsiLayer.Show();
            _mapControl.AddLayerButtom(gsiLayer);
        }

        public void SetMiyakeSamples()
        {
            sampleData sample = new sampleData();
            sample.SetMiyakeSamples(_mapControl);
        }

        PostGisLayer CreateLandForm(MapCanvas canvas)
        {
            PostGisSource source = new PostGisSource("Landform", VectorSourceTypes.MultiLineString, 4301, AzukiMap.CoordinationUnits.DEGREES);
            source.DbName = "miyake";
            source.TableName = "miyake_public_landform_bl";
            source.GeometryColumn = "the_geom";
            source.GetColumnDataUri = "http://azukimap.jp/amdev/getGeomData.php";

            PostGisLayer layer = new PostGisLayer(source, canvas, "contour");
            return layer;
        }

        private void BtnSweep_Click(object sender, RoutedEventArgs e)
        {
            Sweep();
        }

        private void BtnSave_Click(object sender, RoutedEventArgs e)
        {
            _logDisplay.Output = _mapControl.ToXml().ToString();
        }

        void SetWMSLayer()
        {
            WMSSource source = new WMSSource();

            source.RequestUri = "http://orthophoto.mlit.go.jp:8888/wms/service/wmsRasterTileMap";
            source.Layers.Add("ORTHO");
            source.MaxHeight = 910;
            source.MaxWidth = 910;
            source.MaxScale = 50000;
            source.Srid = 4612;
            source.Version = WMSVersion.V1_3_0;
            source.Format = RasterFileSourceFormat.JPEG;
            source.BBoxLatLonOrder = LatLonOrder.LAT_LON;

            MapCanvas canvas = _mapControl.CreateMapCanvas();
            WMSLayer layer = new WMSLayer(source, canvas, "Aero 70's (WMS)");
            layer.MaxScale = source.MaxScale;
            layer.Visiblity = Visibility.Collapsed;

            _mapControl.AddLayerButtom(layer);
        }

        void SetYokohamap()
        {
            PrecisionModel pm = new PrecisionModel();
            GeometryFactory gf = new GeometryFactory();
            GeometryWKTReader wktReader = new GeometryWKTReader(gf);

            MapCanvas canvas_s39 = _mapControl.CreateMapCanvas();
            RasterIndexLayer layer_s39 = new RasterIndexLayer(canvas_s39, "Yokohama s39");

            RasterIndexRecord source_s39 = new RasterIndexRecord();
            source_s39.RasterIndex = "http://azukimap.jp/yokohama/raster/84-5.png";

            source_s39.Extent = (GTPolygon)wktReader.Create(
                @"POLYGON((
		            139.6304340851354 35.44618595903788,
		            139.6662510613415 35.44618595903788,
		            139.6662510613415 35.42484257756843,
		            139.6304340851354 35.42484257756843,
		            139.6304340851354 35.44618595903788
		            ))");
            layer_s39.AddRaster(source_s39);

            _mapControl.AddLayerButtom(layer_s39);

            MapCanvas canvas_s29 = _mapControl.CreateMapCanvas();
            RasterIndexLayer layer_s29 = new RasterIndexLayer(canvas_s29, "Yokohama s29");

            RasterIndexRecord source_s29 = new RasterIndexRecord();
            source_s29.RasterIndex = "http://azukimap.jp/yokohama/raster/034-2.png";

            source_s29.Extent = (GTPolygon)wktReader.Create(
                @"POLYGON((
		            139.6431989695018 35.44922929108722,
		            139.6792616443718 35.44922929108722,
		            139.6792616443718 35.42800623076964,
		            139.6431989695018 35.42800623076964,
		            139.6431989695018 35.44922929108722))");
            layer_s29.AddRaster(source_s29);

            _mapControl.AddLayerButtom(layer_s29);

            MapCanvas canvas_s6 = _mapControl.CreateMapCanvas();
            RasterIndexLayer layer_s6 = new RasterIndexLayer(canvas_s6, "yokohama s9");

            RasterIndexRecord source = new RasterIndexRecord();
            source.RasterIndex = "http://azukimap.jp/yokohama/raster/034.png";

            source.Extent = (GTPolygon)wktReader.Create(
                @"POLYGON((
                    139.6440181048425 35.44944526808909, 
                    139.678676070538  35.44944526808909,
                    139.678676070538  35.42888186512448,
                    139.6440181048425 35.42888186512448, 
                    139.6440181048425 35.44944526808909))");
            layer_s6.AddRaster(source);
            _mapControl.AddLayerButtom(layer_s6);
        }

    }
}
